<template>
	<div ref="monacoEditorRef" class="monaco_editor"></div>
</template>
<script lang="ts" setup>
import axios from 'axios';
import * as monaco from 'monaco-editor';
import { onMounted, ref } from 'vue';

import useElement from '../../../element/hooks/useElement';
import { TablePageType, TabFieldType } from '/@/components/Linxyun/custom/DataStructs/commontype';
import FileIns from '/@/components/Linxyun/FileClient/FileClientApi/file_instance.js';
import { Base64 } from '/@/utils/b64';
const props = withDefaults(
	defineProps<{
		pageInfo?: TablePageType;
		filterIdx: number;
		located: string;
		pageData?: any;
		inputData: Record<string, any>;
		globalData?: any;
		modelValue: string;
		FieldItem: TabFieldType | null;
	}>(),
	{
		located: 'table',
		filterIdx: -1,
		pageData: {},
		globalData: null,
		modelValue: '',
		FieldItem: null,
	}
);
const { FieldItem, located } = toRefs(props);
const emits = defineEmits(['update:modelValue']);

type themeType = 'vs' | 'vs-dark' | 'hc-light' | 'hc-black';
type languageType = 'css' | 'html' | 'json' | 'typescript' | 'javascript';
const theme: themeType = 'vs';
const language: languageType = props.FieldItem?.Language || 'javascript';
const activate = ref(true);
const setting = localStorage.getItem('setting');
const prefixUrl = ref('');
const fileClient = ref();
const oldFileUrl = ref('');
const editorValue = ref('');
const modelMarkersList = ref<any[]>([]);
const init = async () => {
	if (setting) {
		prefixUrl.value = JSON.parse(setting).ImagUrl;
	}
	fileClient.value = await FileIns.instance();

	if (FieldItem.value!.DataStorageMode === 'file') {
		oldFileUrl.value = props.modelValue;
		const url = prefixUrl.value + props.modelValue;
		axios.get(url).then((res: any) => {
			editorValue.value = res.data;
		});
	} else {
		editorValue.value = Base64.decode(props.modelValue).replace(/\\/g, '');
	}
};
init();
// const editorValue = ref(atob(props.modelValue).replace(/\\/g, ''));
const editorConfig: monaco.editor.IStandaloneEditorConstructionOptions = {
	value: '',
	theme: theme,
	language: language,
	readOnly: false,
	tabSize: 2,
	minimap: {
		// 关闭代码缩略图
		enabled: false, // 是否启用预览图
	},
	foldingStrategy: 'indentation', // 代码可分小段折叠
	autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
	autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
	autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
	cursorBlinking: 'solid', // 光标动画样式
	folding: true, // 是否启用代码折叠
	renderLineHighlight: 'all', // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
	comments: {
		ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
		insertSpace: true, // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
	},
};
const { handleDisable } = useElement(located, FieldItem.value!, editorValue, props);

handleDisable(activate);

const monacoEditorRef = ref();
const editor = ref<null | monaco.editor.IStandaloneCodeEditor>(null);
const initEditor = () => {
	console.log('monacoEditorRef', monacoEditorRef);
	editor.value = monaco.editor.create(monacoEditorRef.value, editorConfig);
	toRaw(editor.value)?.setValue(editorValue.value);
	// 监听值的变化
	editor.value?.onDidChangeModelContent(() => {
		const value = toRaw(editor.value)?.getValue(); // 给父组件实时返回最新文本
		console.log('onDidChangeModelContent value:', value);
		console.log('getModelMarkers', modelMarkersList.value);
		emits('update:modelValue', value);
	});
};
const filePostfix = {
	javascript: 'js',
	typescript: 'ts',
	json: 'json',
	html: 'html',
	css: 'css',
};
// 上传
const uploadSubmit = async () => {
	// 保存为文件
	if (FieldItem.value!.DataStorageMode === 'file') {
		if (editorValue.value) {
			const res = await fileClient.value?.uploadContent('file.' + filePostfix[language], new Blob([editorValue.value]));
			if (res) {
				console.log('uploadSubmit', res);
				if (oldFileUrl.value) {
					fileClient.value.deleteFile(oldFileUrl.value);
				}
				return res;
			}
		}
	}
};

onMounted(() => {
	setTimeout(() => {
		initEditor();
		toRaw(editor.value)?.updateOptions({
			readOnly: !activate.value,
		});
	}, 500);
});
onUnmounted(() => {
	toRaw(editor.value)?.dispose();
});
defineExpose({
	uploadSubmit,
});
</script>
<style lang="scss" scoped>
.monaco_editor {
	height: 300px;
	border: 1px solid #dcdfe6;
}
</style>
